package com.jwthhealth_pub.wristband.service;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.support.annotation.Nullable;

import com.jwthhealth_pub.common.LogUtil;
import com.jwthhealth_pub.old.common.Constant;
import com.jwthhealth_pub.wristband.broadcast.ServiceOptReceiver;
import com.jwthhealth_pub.wristband.broadcast.WristBandReceiver;
import com.jwthhealth_pub.wristband.manager.WristbandManager;
import com.jwthhealth_pub.wristband.presenter.IWristBandServicePresenter;
import com.jwthhealth_pub.wristband.presenter.IWristBandServicePresenterCompl;
import com.jwthhealth_pub.wristband.service.model.BloodHeartPastModule;
import com.jwthhealth_pub.wristband.service.model.SleepTimeModule;
import com.jwthhealth_pub.wristband.service.model.StepPassDataModule;
import com.jwthhealth_pub.wristband.setting.view.WristBandConnManaActivity;
import com.jwthhealth_pub.wristband.steps.bean.StepsTimeModel;
import com.jwthhealth_pub.wristband.steps.db.StepsTimeDao;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static com.jwthhealth_pub.common.LogUtil.makeLogTag;
import static com.jwthhealth_pub.wristband.broadcast.ServiceOptReceiver.SERVICE_OPT;

/**
 * 蓝牙、手环服务
 * Created by liuzhen on 2017/12/16.
 */

public class WristBandService extends Service implements IWristBandServicePresenter.view {

    private static final String TAG = makeLogTag(WristBandService.class);

    public static boolean isConn = false;

    private IWristBandServicePresenter.presenter mPresenter;

    private BlueToothStateReceiver mBlueToothStateReceiver;

    List<byte[]> mBleHistoryValue;

    // 0 历史睡眠计步 1 定时心率
    private int notifyReceiveState = 0;

    //定时心率所需变量
    private int tempCount = 0;
    private int tempDataPackageCount = 0;
    private int tempDataPackageIndex = 0;
    private HashMap<Integer, String> tempPartPackages;
    private int mInfoState = 0;
    private String mManufacturer, mModel, mSerial, mHardware, mSoftware;

    // TODO: 2018/1/4 不在一个进程里 ，暂时设置成静态
    public static BluetoothGatt mConnGatt;
    private ServiceOptReceiver mServiceOptReceiver;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        try {
            if (mPresenter == null)
                mPresenter = new IWristBandServicePresenterCompl(this);
        } catch (Exception e) {
            //不支持蓝牙服务
            notSupportBlueTooth();

            return super.onStartCommand(intent, flags, startId);
        }

        mPresenter.enableBlutTooth();

        registBlueTooth();

        registerServiceOpt();

        return super.onStartCommand(intent, flags, startId);
    }

    private void registerServiceOpt() {
        mServiceOptReceiver = new ServiceOptReceiver();
        mServiceOptReceiver.setOnServiceOpt(new ServiceOptReceiver.ServiceOpt() {
            @Override
            public void onOptStop() {

                if (mConnGatt != null) {
                    mConnGatt.disconnect();
                    isConn = false;
                }
//                stopSelf();
            }
        });

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(SERVICE_OPT);
        registerReceiver(mServiceOptReceiver, intentFilter);
    }

    public void scan() {
        if (mPresenter == null)
            try {
                mPresenter = new IWristBandServicePresenterCompl(this);
            } catch (Exception e) {
                e.printStackTrace();
            }

        mPresenter.scan();
    }

    public void cancelScan() {
        mPresenter.cancelScan();
    }

    public void conn(BluetoothDevice bluetoothDevice, final WristBandConnManaActivity.bleConnState bleConnState) {
        mPresenter.connect(bluetoothDevice, new BluetoothGattCallback() {

            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                super.onConnectionStateChange(gatt, status, newState);

                switch (newState) {
                    case BluetoothProfile.STATE_CONNECTED:
                        gatt.discoverServices();//必须加
                        bleConnState.conn();
                        isConn = true;
                        break;
                    case BluetoothProfile.STATE_DISCONNECTED:
                        gatt.close();
                        bleConnState.disConn();
                        isConn = false;
                        break;
                    default:
                }
            }

            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                super.onServicesDiscovered(gatt, status);

                mConnGatt = gatt;
                mPresenter.setGatt(gatt);

                //读取手环信息
                mPresenter.readwristBandInfo(mInfoState);

                mPresenter.startBlood();
                mPresenter.readStep();
                mPresenter.notifyStep();
                mPresenter.notifyBlood();
                mPresenter.notifyFatigue();

                // TODO: 2017/12/28 用户信息
                mPresenter.writeUserinfo();
                mPresenter.readFatifue();

                if (notifyReceiveState == 0) {
                    LogUtil.i("readPassStepAndSleep",TAG);
                    mPresenter.readPassStepAndSleep();
                }

                // todo 矫正时间 不需要每次都矫正时间 存在不能并发的bug
                mPresenter.correctTime();

            }

            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                super.onCharacteristicChanged(gatt, characteristic);
                updateBelValue(gatt, characteristic);
            }

            @Override
            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                super.onCharacteristicRead(gatt, characteristic, status);
//                mPresenter.setGatt(gatt);
                updateBelValue(gatt, characteristic);
            }
        });
    }

    private void updateBelValue(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {

        switch (characteristic.getInstanceId()) {
            case WristbandManager.BLE_INFO:
                break;
            case WristbandManager.BLE_BASE_INFO_ONE:
            case WristbandManager.BLE_BASE_INFO_TWO:
            case WristbandManager.BRACELET_MAC_ADDRESS:
            case WristbandManager.BLE_BASE_INFO_THI:
            case WristbandManager.BLE_BASE_INFO_FOR:
                byte[] value = characteristic.getValue();

                String info = "";
                try {
                    info = new String(value, "ascii");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                if (mInfoState == 0) {
                    //制造商
                    mManufacturer = info;
                    mPresenter.readwristBandInfo(++mInfoState);
                } else if (mInfoState == 1) {
                    //产品型号
                    mModel = info;
                    mPresenter.readwristBandInfo(++mInfoState);
                } else if (mInfoState == 2) {
                    mSerial = info;
                    mPresenter.readwristBandInfo(++mInfoState);

                } else if (mInfoState == 3) {
                    mHardware = info;
                    mPresenter.readwristBandInfo(++mInfoState);
                } else if (mInfoState == 4) {
                    mSoftware = info;
                    if (mManufacturer != null && mModel != null && mSerial != null && mHardware != null)
                        mPresenter.postWristBandInfo(mManufacturer, mModel, mSerial, mHardware, mSoftware);
                }
                break;
            //步数
            case WristbandManager.STEP_CHARAC_ID:
                byte[] stepValue = characteristic.getValue();

                byte oxyValue = stepValue[4];
                mPresenter.sendServiceBrocast(WristBandReceiver.NOTIFY_OXYGEN_CHANGED, oxyValue);

                // TODO: 2017/12/25 step kcal odo
                int step = mPresenter.calcStep(stepValue);

                mPresenter.sendServiceBrocast(WristBandReceiver.NOTIFY_STEP_CHANGED, step);
                break;
            case WristbandManager.KCAL_SPORTSTATE_ID:
                byte[] value1 = characteristic.getValue();

                if (value1[0] == 6) {
                    //疲劳度
                    byte fatifue = value1[13];
                    mPresenter.sendServiceBrocast(WristBandReceiver.NOTIFY_FATIFUE_CHANGED, fatifue);
                }

                break;
            //mass data
            case WristbandManager.MASSDATA_CHARAC_ID:
                if (notifyReceiveState == 0) {
                    calcPassStepAndSleep(characteristic);
                } else if (notifyReceiveState == 1) {
                    calcPassStaticHeart(characteristic);
                }
                break;
            case WristbandManager.HEART_CHARAC_ID:
                //心率
                byte[] heartValeus = characteristic.getValue();
                mPresenter.sendServiceBrocast(WristBandReceiver.NOTIFY_HEART_CHANGED, heartValeus);
                break;
            case WristbandManager.BLOOD_NOTIFY_CHARAC_ID:
                byte[] bloodValues = characteristic.getValue();
                mPresenter.sendServiceBrocast(WristBandReceiver.NOTIFY_BLOOD_CHANGED, bloodValues);

                break;
            default:
                break;
        }
    }

    private void calcPassStaticHeart(BluetoothGattCharacteristic characteristic) {

        tempCount++;

        byte[] values = characteristic.getValue();

        if (tempCount <= 7) {
            if (values[10] == 18 && values[11] == -112) {//计时心率有效标记
                //记录时间
                int stepStartTime = WristbandManager.bytesToInt(new byte[]{values[4], values[5], values[6], values[7]}, 4);
                int count = WristbandManager.bytesToInt(new byte[]{values[8], values[9]}, 2);
                tempDataPackageCount += count;
                tempPartPackages.put(count, stepStartTime + "");
            }
        } else if (tempCount > 7) {
            tempDataPackageIndex += 2;

            mBleHistoryValue.add(values);

            if (tempDataPackageIndex >= tempDataPackageCount) {
                //读取完毕
                ArrayList<BloodHeartPastModule> passBloodHeartModule = new ArrayList<>();

                int tempDataIndex = 0;

                for (int i = 0; i < mBleHistoryValue.size(); i++) {

                    byte[] bs = mBleHistoryValue.get(i);

                    if (bs.length == 20) {
                        for (int key : tempPartPackages.keySet()) {
                            if (tempDataIndex <= key) { //每个包里包含两条数据
                                // TODO: 2018/1/2 过滤数据
                                if (tempPartPackages.get(key).equals("0")) continue;

                                int checkHour = WristbandManager.bytesToInt(new byte[]{bs[4]}, 1);
                                int checkMinute = WristbandManager.bytesToInt(new byte[]{bs[5]}, 1);
                                int checkHeart = WristbandManager.bytesToInt(new byte[]{bs[6]}, 1);
                                int checkSpb = WristbandManager.bytesToInt(new byte[]{bs[7]}, 1);
                                int checkDpb = WristbandManager.bytesToInt(new byte[]{bs[8]}, 1);

                                passBloodHeartModule.add(new BloodHeartPastModule(
                                        tempPartPackages.get(key),
                                        checkHour + ":" + checkMinute,
                                        checkHeart + "", checkSpb + "", checkDpb + ""
                                ));

                                break;
                            }
                        }

                        //每个数据包包含两组数据
                        for (int key : tempPartPackages.keySet()) {
                            if (tempDataIndex <= key) {
                                if (tempPartPackages.get(key).equals("0")) continue;

                                int checkHour = WristbandManager.bytesToInt(new byte[]{bs[12]}, 1);
                                int checkMinute = WristbandManager.bytesToInt(new byte[]{bs[13]}, 1);
                                int checkHeart = WristbandManager.bytesToInt(new byte[]{bs[14]}, 1);
                                int checkSpb = WristbandManager.bytesToInt(new byte[]{bs[15]}, 1);
                                int checkDpb = WristbandManager.bytesToInt(new byte[]{bs[16]}, 1);

//                                int checkHour = WristbandManager.calc(bs[12]);
//                                int checkMinute = WristbandManager.calc(bs[13]);
//                                int checkHeart = WristbandManager.calc(bs[14]);
//                                int checkSpb = WristbandManager.calc(bs[15]);
//                                int checkDpb = WristbandManager.calc(bs[16]);

                                passBloodHeartModule.add(new BloodHeartPastModule(
                                        tempPartPackages.get(key),
                                        checkHour + ":" + checkMinute,
                                        checkHeart + "", checkSpb + "", checkDpb + ""
                                ));

                                break;
                            }
                        }
                        tempDataIndex++;
                    }
                }

//                for (BloodHeartPastModule module: passBloodHeartModule)
//                    Log.d(TAG, "module:" + module.toString());

                mPresenter.postBloodAndHeartData(passBloodHeartModule);
            }
        }
    }

    private void calcPassStepAndSleep(BluetoothGattCharacteristic characteristic) {
        byte[] value = characteristic.getValue();

        if (mBleHistoryValue == null)
            mBleHistoryValue = new ArrayList<>();

        mBleHistoryValue.add(value);
        if (value[0] == value[2] && value[1] == value[3]) {
            // 数据是否传输完毕
            List<List<Byte>> bytes = mPresenter.dataReconstitution(mBleHistoryValue);

            List<SleepTimeModule> sleepPassDataList = new ArrayList<>();
            List<StepPassDataModule> stepPassDataModules = new ArrayList<>();

            for (int i = 0; i < bytes.size(); i++) {
                List<Byte> record = bytes.get(i);
                int endIndex = record.size();
                if (record.get(endIndex - 4) == -112 && record.get(endIndex - 3) == 120 && record.get(endIndex - 2) == 86 && record.get(endIndex - 1) == 52) {
                    //计步数据
                    int stepStartTime = WristbandManager.bytesToInt(new byte[]{record.get(0), record.get(1), record.get(2), record.get(3)}, 4);
                    int stepTotalTime = WristbandManager.bytesToInt(new byte[]{record.get(4), record.get(5), record.get(6), record.get(7)}, 4);
                    int stepTotal = WristbandManager.bytesToInt(new byte[]{record.get(8), record.get(9), record.get(10), record.get(11)}, 4);

                    //24小时步数统计
                    List<Byte> hoursData = new ArrayList<>();
                    for (int j = 12; j < record.size() - 4; j++) {
                        Byte b = record.get(j);
                        LogUtil.i("origan:"+b,TAG);
                        hoursData.add(b);
                    }
                    // TODO: 2018/1/8
//                    List<String> filtrationList = filtration(hoursData);
                    List<String> filtrationList = null;
                    stepPassDataModules.add(new StepPassDataModule(stepStartTime + "",
                            stepTotalTime + "", stepTotal + "", filtrationList));

                } else if (record.get(endIndex - 4) == 1 && record.get(endIndex - 3) == -119 && record.get(endIndex - 2) == 103 && record.get(endIndex - 1) == 69) {
                    //睡眠数据
                    int sleepStartTime = WristbandManager.bytesToInt(new byte[]{record.get(0), record.get(1), record.get(2), record.get(3)}, 4);
                    int sleepEndTime = WristbandManager.bytesToInt(new byte[]{record.get(4), record.get(5), record.get(6), record.get(7)}, 4);

                    int awakeTime = WristbandManager.bytesToInt(new byte[]{record.get(8), record.get(9)}, 2);
                    if (!filtration(awakeTime)) continue;

                    int lightSleepTime = WristbandManager.bytesToInt(new byte[]{record.get(10), record.get(11)}, 2);
                    if (!filtration(lightSleepTime)) continue;

                    int deepSleepTime = ((sleepEndTime - sleepStartTime) / 60) - awakeTime - lightSleepTime;
                    if (!filtration(deepSleepTime)) continue;

                    //24小时活跃指数
                    List<Byte> hoursData = new ArrayList<>();
                    for (int j = 12; j < record.size() - 4; j++) {
                        Byte b = record.get(j);
                        hoursData.add(b);
                    }
                    List<String> filtrationList = filtration(hoursData);

                    sleepPassDataList.add(new SleepTimeModule(sleepStartTime + "", sleepEndTime + "",
                            awakeTime + "", lightSleepTime + "", deepSleepTime + "", filtrationList));
                }
            }

            //发送睡眠状态广播
            if (sleepPassDataList.size() < 1) return;
            SleepTimeModule sleepTimeModule = sleepPassDataList.get(sleepPassDataList.size() - 1);

            int[] sleepList = new int[29];

            String startSleepTime = sleepTimeModule.getStartSleepTime();
            String endSleepTime = sleepTimeModule.getEndSleepTime();
            int sleepTotlaTime = Integer.parseInt(endSleepTime) - Integer.parseInt(startSleepTime);

            String sleepDeepTime = sleepTimeModule.getDeepSleepTime();
            String sleepLightTime = sleepTimeModule.getLightSleepTime();
            String awakeTime = sleepTimeModule.getAwakTime();

            sleepList[0] = Integer.parseInt(startSleepTime);
            sleepList[1] = Integer.parseInt(endSleepTime);
            sleepList[2] = Integer.parseInt(sleepDeepTime);
            sleepList[3] = Integer.parseInt(sleepLightTime);
            sleepList[4] = Integer.parseInt(awakeTime);
            for (int i = 0; i < 24; i++) {
                sleepList[5 + i] = Integer.parseInt(sleepTimeModule.getHoursData().get(i));
            }

            mPresenter.sendServiceBrocast(WristBandReceiver.NOTIFY_SLEEP_CHANGED, sleepList);

//            for (SleepTimeModule module : sleepPassDataList)
//                Log.d(TAG, module.toString());

//            for (StepPassDataModule module : stepPassDataModules)
//                Log.d(TAG, "module:" + module);

            mPresenter.postStepAndSleepData(sleepPassDataList, stepPassDataModules);

            //心率历史读取完毕，读取定时心率历史数据
            notifyReceiveState = 1;
            mPresenter.getPassStaticHeart();
            mBleHistoryValue = new ArrayList<>();
            tempPartPackages = new HashMap<>();
        }
    }

    private List<String> filtration(List<Byte> hoursData) {
        List<String> list = new ArrayList<>();

        int j=0;

        for (int i = 0; i < hoursData.size(); i++) {
            if (i % 2 == 1) {
                int validData = WristbandManager.bytesToInt(new byte[]{hoursData.get(i - 1), hoursData.get(i)}, 2);
                LogUtil.i("calc:"+validData+" byte:" + hoursData.get(i) + hoursData.get(i - 1), TAG);
                if (filtration(validData))
                    list.add(String.valueOf(validData));
                else
                    list.add("0");
            }
        }

        return list;
    }

    private boolean filtration(int sleepStartTime) {
        boolean isValid = true;

        if (sleepStartTime < 0 || String.valueOf(sleepStartTime).length() >= 5)
            isValid = false;

        return isValid;
    }

    /**
     * 存储在本地数据库里
     *
     * @param stepPassDataModules data
     */
    private void saveStepData(List<StepPassDataModule> stepPassDataModules) {
        StepsTimeDao stepsTimeDao = StepsTimeDao.getInstance();
        for (StepPassDataModule moudule : stepPassDataModules) {

            boolean b = stepsTimeDao.queryByDateEqual(moudule.getRecordTime());
            if (!b) {
                List<String> hourStep = moudule.getHourStep();
                stepsTimeDao.add(new StepsTimeModel(moudule.getRecordTime(), moudule.getTotalStep(), "", "", hourStep));
            }
        }
    }

    /**
     * 蓝牙状态广播
     */
    private void registBlueTooth() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        mBlueToothStateReceiver = new BlueToothStateReceiver();
        registerReceiver(mBlueToothStateReceiver, intentFilter);

//        gattDisReceiver = new GattDisReceiver();
//        IntentFilter intentFilter1 = new IntentFilter();
//        intentFilter1.addAction(DISCONN);
//        registerReceiver(gattDisReceiver, intentFilter);
    }

    private class BlueToothStateReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                        BluetoothAdapter.ERROR);
                switch (state) {
                    case BluetoothAdapter.STATE_OFF:
                        //发送蓝牙关闭广播
                        mPresenter.sendServiceBrocast(WristBandReceiver.BLUETOOTH_OFF);
                        break;
                    case BluetoothAdapter.STATE_TURNING_OFF:
                        // 蓝牙关闭 关闭服务
                        onDestroy();
                        break;
                    case BluetoothAdapter.STATE_ON:
                        // 蓝牙开启
                        break;
                    case BluetoothAdapter.STATE_TURNING_ON:
                        // 蓝牙正在开启
                        break;
                }
            }
        }
    }

    private void notSupportBlueTooth() {
        Intent intent = new Intent();
        intent.setAction(this.getPackageName());
        intent.putExtra(Constant.TAG, WristBandReceiver.BLUETOOTH_NOTSUPPORT);
        sendBroadcast(intent);

        onDestroy();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mBlueToothStateReceiver);
        unregisterReceiver(mServiceOptReceiver);
    }
}
